#ifndef es_h
#define es_h

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include "parametros.h"

namespace SimuladorAD {
   /** \brief Classe para controlar a saída de dados usados para plotar gráficos.
    * 
    * A classe usa buffers gerenciáveis std::stringstream para acumular na memória 
    * os dados gerados durante a simulação. Permite descarregar o buffer no momento desejado,
    * evitando fazer E/S no meio da simulação.
    */
    class SaidaGrafico {
        int m_num_filas;
        std::map<const char*, std::stringstream* > m_buffers_trans[2]; /**< Buffers (dois por grandeza, um para cada fila) */
        
        public:
        /**
         * Construtor da classe
         *
         * \param num_filas número de filas do sistema.
         */
        SaidaGrafico(int num_filas);

        /** Destrutor da classe. */
        ~SaidaGrafico();

        /**
         * Escreve uma estimativa no buffer.
         *
         * \param grandeza Grandeza a qual se relaciona a estimativa. Ex: T, N, W, etc.
         * \param fila Fila a qual se relaciona a estimativa.
         * \param est_media Valor da estimativa da média.
         * \param est_media Quantidade de amostras para esta estimativa.
         * \param est_media Valor da estimativa da variância.
         * \param est_media Valor da estimativa do intervalo de confiança.
         */
        void escrever_estimativa(const char* grandeza, 
                                 int fila, 
                                 const double& est_media, 
                                 const double& quant_amostras, 
                                 const double& est_var, 
                                 const double& ic);

        /** Escreve o conteúdo dos buffers em arquivos 
         *
         * \param caminho Caminho do arquivo no sistema de arquivos.
         * \param prefixo Prefixo do nome dos arquivos.
         * */
        void escrever_arquivos(const char* caminho, const char* prefixo);
    };

    /**
     * \brief Classe para controlar a entrada de parâmetros no simulador pela entrada padrão (stdin)
     */
    class EntradaPadrao {
        public:
        /**
         * Lê da entrada padrão para uma instância de configuração do simulador.
         *
         * \param conf Objeto de configuração do simulador que será preenchido.
         */
        static void ler_config(Configuracao& conf);
    };

    /**
     * \brief Classe para controlar a saída de resultados e mensagens do simulador
     * 
     * A classe usa um buffer para os resultados e outro para as mensagens impressas em 
     * modo verboso, possibilitando escrever a saída do simulador em um único momento.
     */
    class SaidaPadrao {
        public:
        std::stringstream *buffer_saida; /**< buffer para os resultados */
        std::stringstream *buffer_msg; /**< buffer para as mensagens */

        /** Construtor padrão da classe */
        SaidaPadrao();

        ~SaidaPadrao();

        /** Escreve o conteúdo dos buffers em arquivos 
         *
         * \param caminho Caminho do arquivo no sistema de arquivos.
         * \param prefixo_res Prefixo do nome dos arquivos de resultados.
         * \param prefixo_msg Prefixo do nome dos arquivos de mensagens.
         * */
        void escrever_arquivos(const char* caminho, std::string prefixo_res, std::string prefixo_msg);
    };
}

#endif
